package com.ft.sso.secrityauthor2sso.config;

import com.ft.sso.secrityauthor2sso.extent.JwtExtentConfig;
import com.ft.sso.secrityauthor2sso.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author RenPu
 * @Date 2022/9/28 14:42
 * @Version 1.0
 * @Description:
 **/
@Configuration
@EnableAuthorizationServer  //让授权服务器生效
public class AuthenticationServerConfig2 extends AuthorizationServerConfigurerAdapter {

    @Autowired
    @Lazy
    private PasswordEncoder passwordEncoder;  //加密

    @Autowired
    private UserService userService;    //用户信息的验证

    @Autowired
    @Qualifier("jwtTokenStore")
    private TokenStore tokenStore;     //token的存储

    @Autowired
    private AuthenticationManager authenticationManager;  //认证管理器

    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    @Autowired
    private JwtExtentConfig jwtExtentConfig;  //jwt增强器对象






    /**
     * 1:认证管理进行管理
     * 2：token存储的方式
     * 3：刷新的token是否可以重复使用
     * 4：用户信息的校验
     * 5：请求方式的支持：例如:GET,POST
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

        //创建TokenEnhancerChain对象
        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
        List<TokenEnhancer> deleget = new ArrayList<>();
        deleget.add(jwtAccessTokenConverter);
        deleget.add(jwtExtentConfig);
       enhancerChain.setTokenEnhancers(deleget);

        endpoints.authenticationManager(authenticationManager)  //使用密码模式需要配置的
                .reuseRefreshTokens(true)                      //refresh_code是否可重复使用
                .userDetailsService(userService)                //刷新令牌授权包含对用户信息的检查
                .tokenStore(tokenStore)                         //指定token存储到redis
                .accessTokenConverter(jwtAccessTokenConverter)
                .tokenEnhancer(enhancerChain)                   //配置自定义增强器加入如
                .allowedTokenEndpointRequestMethods             //支持GET,POST请求
                (HttpMethod.GET,HttpMethod.POST);

    }


    /**
     * 设置支撑表单验证
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
         security.allowFormAuthenticationForClients();
    }


    /**
     * 配置授权服务器所需的必要参数
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                //配置client_id(自定义)
                .withClient("client")
                //配置client_secret()
                .secret(passwordEncoder.encode("123123"))
                //配置访问token的时间
                .accessTokenValiditySeconds(3600)
                //配置刷新token的时间
                .refreshTokenValiditySeconds(864000)
                //配置redirect_uri:授权成功后进行跳转
                .redirectUris("http://www.baidu.com")
                //配置申请的权限范围
                .scopes("all")
                /**
                 * 配置：grant_type; 表示授权码类型
                 * authorization_code:授权码模式
                 * implicit: 简化模式
                 * password：密码模式
                 * client_credentials：客户端模式
                 *  refresh_token：更新令牌
                 */

                //Password模式：http:localhost:8086/oauth/token?username=renpu&password=123456&grant_type=password&client_id=client&client_secret=123123&scope=all


                .authorizedGrantTypes("authorization_code","implicit",
                                      "password","client_credentials","refresh_token");


    }




}
